package com.cb2.algorithm.leetcode;

import java.util.ArrayList;
import java.util.List;

public class Printer {

    public static void printListNode(ListNode head) {
        ListNode currNode = head;
        while (currNode != null) {
            System.out.print(currNode.val + " -> ");
            currNode = currNode.next;
        }
        System.out.println("null");
    }

    public static void printListInteger(List<Integer> listList) {
        if (listList == null || listList.size() == 0) {
            System.out.println("[]");
            return;
        }
        System.out.print("[");
        for (int i = 0; i < listList.size(); i++) {
            if (i == listList.size() - 1) {
                System.out.print(listList.get(i));
            } else {
                System.out.print(listList.get(i) + ",");
            }
        }
        System.out.println("]");
    }

    public static void printListString(List<String> listList) {
        if (listList == null || listList.size() == 0) {
            System.out.println("[]");
            return;
        }
        System.out.print("[");
        for (int i = 0; i < listList.size(); i++) {
            if (i == listList.size() - 1) {
                System.out.print(listList.get(i));
            } else {
                System.out.print(listList.get(i) + ",");
            }
        }
        System.out.println("]");
    }

    public static void printListListInteger(List<List<Integer>> listList) {
        if (listList == null || listList.size() == 0) {
            System.out.println("[]");
            return;
        }
        System.out.print("[");
        for (int i = 0; i < listList.size(); i++) {
            System.out.print("[");
            int size = listList.get(i).size();
            for (int i1 = 0; i1 < size; i1++) {
                if (i1 == size - 1) {
                    System.out.print(listList.get(i).get(i1));
                } else {
                    System.out.print(listList.get(i).get(i1) + ",");
                }
            }
            if (i == listList.size() - 1) {
                System.out.print("]");
            } else {
                System.out.print("], ");
            }
        }
        System.out.print("]");
        System.out.println();
    }

    public static void printListListString(List<List<String>> listList) {
        if (listList == null || listList.size() == 0) {
            System.out.println("[]");
            return;
        }
        System.out.print("[");
        for (int i = 0; i < listList.size(); i++) {
            System.out.print("[");
            int size = listList.get(i).size();
            for (int i1 = 0; i1 < size; i1++) {
                if (i1 == size - 1) {
                    System.out.print(listList.get(i).get(i1));
                } else {
                    System.out.print(listList.get(i).get(i1) + ",");
                }
            }
            if (i == listList.size() - 1) {
                System.out.print("]");
            } else {
                System.out.print("], ");
            }
        }
        System.out.print("]");
        System.out.println();
    }

    public static void printListList(List<List<String>> listList) {
        if (listList == null || listList.size() == 0) {
            System.out.println("[]");
            return;
        }
        System.out.print("[");
        for (int i = 0; i < listList.size(); i++) {
            System.out.print("[");
            int size = listList.get(i).size();
            for (int i1 = 0; i1 < size; i1++) {
                if (i1 == size - 1) {
                    System.out.print(listList.get(i).get(i1));
                } else {
                    System.out.print(listList.get(i).get(i1) + ",");
                }
            }
            if (i == listList.size() - 1) {
                System.out.print("]");
            } else {
                System.out.print("], ");
            }
        }
        System.out.print("]");
        System.out.println();
    }

    public static void printArrayInt(int[] nums) {
        System.out.print("[");
        for (int i = 0; i < nums.length; i++) {
            if (i != nums.length - 1) {
                System.out.print(nums[i] + ",");
            } else {
                System.out.print(nums[i]);
            }
        }
        System.out.println("]");
    }

    // 层序遍历打印树节点

    static int height = 0;
    static int valMaxLength = 1;

    public static void printTreeNode(TreeNode root) {
        System.out.println("*****************************");
        List<List<String>> lists = printTreeHelper(root);
        for (List<String> list : lists) {
            for (String s : list) {
                StringBuilder builder = new StringBuilder();
                for (int i = 0; i < valMaxLength - s.length(); i++) {
                    builder.append(" ");
                }
                builder.append(s);
                System.out.print(builder);
            }
            System.out.println();
        }
        System.out.println("*****************************");
    }

    private static List<List<String>> printTreeHelper(TreeNode root) {
        getMaxHeight(root, 0);
        int row = height + 1;
        int col = (int) (Math.pow(2, height + 1) - 1);
        List<List<String>> res = new ArrayList<>();
        for (int i = 0; i < row; i++) {
            List<String> tempList = new ArrayList<>();
            for (int j = 0; j < col; j++) {
                tempList.add("");
            }
            res.add(tempList);
        }
        fillVal(root, 0, (col - 1) >> 1, res);
        return res;
    }

    private static void fillVal(TreeNode root, int row, int col, List<List<String>> res) {
        if (root == null) {
            if (row < res.size() && col < res.get(0).size()) {
                res.get(row).set(col, "n");
            }
            return;
        }
        String value = String.valueOf(root.val);
        valMaxLength = Math.max(value.length(), valMaxLength);
        res.get(row).set(col, value);
        fillVal(root.left, row + 1, col - (int) Math.pow(2, height - row - 1), res);
        fillVal(root.right, row + 1, col + (int) Math.pow(2, height - row - 1), res);
    }

    private static void getMaxHeight(TreeNode root, int currLevel) {
        if (root == null) {
            return;
        }
        if (currLevel > height) {
            height = currLevel;
        }
        getMaxHeight(root.left, currLevel + 1);
        getMaxHeight(root.right, currLevel + 1);
    }
}
